//
//  AGLKVertexAttribArrayBuffer.m
//  OpenGLES_Learning
//
//  Created by vandong on 7/29/13.
//  Copyright (c) 2013 Mac Center. All rights reserved.
//

#import "AGLKVertexAttribArrayBuffer.h"

@interface AGLKVertexAttribArrayBuffer ()
@property (nonatomic, assign) GLsizeiptr bufferSizeBytes;
@property (nonatomic, assign) GLsizeiptr stride;
@end

@implementation AGLKVertexAttribArrayBuffer
@synthesize glName;
@synthesize bufferSizeBytes;
@synthesize stride;


- (id)initWithAttribStride:(GLsizeiptr)aStride numberOfVertices:(GLsizei)count data:(const GLvoid *)dataPtr usage:(GLenum)usage
{
    NSParameterAssert(0 < aStride); NSParameterAssert(0 < count); NSParameterAssert(NULL != dataPtr);
    if(nil != (self = [super init]))
    {
        stride = aStride; bufferSizeBytes = stride * count;
        glGenBuffers(1, &glName);
        glBindBuffer(GL_ARRAY_BUFFER, self.glName);
        glBufferData(GL_ARRAY_BUFFER, // STEP 3 GL_ARRAY_BUFFER,
                     bufferSizeBytes,// Initialize buffer contents bufferSizeBytes,
                     dataPtr,// Number of bytes to copy dataPtr, // Address of bytes to copy usage);
                     usage);// Hint: cache in GPU memory
        NSAssert(0 != glName, @"Failed to generate glName");
    }
    
    return self;
}

/////////////////////////////////////////////////////////////////
// This method loads the data stored by the receiver.
- (void)reinitWithAttribStride:(GLsizeiptr)aStride
              numberOfVertices:(GLsizei)count
                         bytes:(const GLvoid *)dataPtr
{
    NSParameterAssert(0 < aStride);
    NSParameterAssert(0 < count);
    NSParameterAssert(NULL != dataPtr);
    NSAssert(0 != glName, @"Invalid name");
    
    self.stride = aStride;
    self.bufferSizeBytes = aStride * count;
    
    glBindBuffer(GL_ARRAY_BUFFER,  // STEP 2
                 self.glName);
    glBufferData(                  // STEP 3
                 GL_ARRAY_BUFFER,  // Initialize buffer contents
                 bufferSizeBytes,  // Number of bytes to copy
                 dataPtr,          // Address of bytes to copy
                 GL_DYNAMIC_DRAW); 
}


- (void)prepareToDrawWithAttrib:(GLuint)index numberOfCoordinates:(GLint)count attribOffset:(GLsizeiptr)offset shouldEnable:(BOOL)shouldEnable
{
    NSParameterAssert((0 < count) && (count < 4)); NSParameterAssert(offset < self.stride); NSAssert(0 != glName, @"Invalid glName");
    glBindBuffer(GL_ARRAY_BUFFER, self.glName);
    if(shouldEnable)
    {
        glEnableVertexAttribArray( index);
    }
    
    glEnableVertexAttribArray( index);
    glVertexAttribPointer( index, count, GL_FLOAT, GL_FALSE, self.stride, NULL + offset);
}

- (void)drawArrayWithMode:(GLenum)mode startVertexIndex:(GLint)first
         numberOfVertices:(GLsizei)count {
    NSAssert(self.bufferSizeBytes >=
             ((first + count) * self.stride),
             @"Attempt to draw more vertex data than available.");
    glDrawArrays(mode, first, count); // Step 6
}

- (void)dealloc
{
    // Delete buffer from current context
    if (0 != glName)
    {
        glDeleteBuffers (1, &glName);
         glName = 0;
    }
}
@end
